package flex.cc.store.service.impl;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import flex.cc.PublicUtil;
import flex.cc.basicinformation.dao.ValueAddedServiceProviderDao;
import flex.cc.basicinformation.entity.ValueAddedServiceProviderEntity;
import flex.cc.store.dao.StorePackageDao;
import flex.cc.store.dto.entity.StorePackageEntity;
import flex.cc.store.dto.vo.StoreInfoVo;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Service;

import flex.cc.store.dao.StoreInfoDao;
import flex.cc.store.dto.entity.StoreInfoEntity;
import flex.cc.store.service.StoreInfoService;

/**
 *
 * @author WANGCONG
 * 2021年12月16日下午2:14:37
 * @desc 门店信息实现层
 */
@Service("storeInfoService")
public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoDao, StoreInfoEntity> implements StoreInfoService {

	@Resource
	private StoreInfoDao storeInfoDao;
	@Resource
	private StorePackageDao storePackageDao;
	@Resource
	private ValueAddedServiceProviderDao valueAddedServiceProviderDao;

	/**
	*
	* @author WANGCONG
	* 2021年12月17日下午16:12:25
	* @desc 门店信息批量插入
	*/
	@Override
	public void insertBatch(List<StoreInfoEntity> storeInfoList) {
		storeInfoDao.insertBatch(storeInfoList);
	}

    /**
     * @param params 查询参数
     * @return
     * @description 根据参数查询门店信息实体
     * @author wkangle
     * @time 2021-12-16 14:50:15
     * @exception/throws
     */
    @Override
    public StoreInfoEntity getOneByParams(Map<String, Object> params) {
        return storeInfoDao.getOneByParams(params);
    }

    /**
     * @param reqVo 服务项目、定位坐标、城市
     * @return
     * @description 根据服务项目、定位所在城市查询门店列表（默认营业中状态），根据距离排序
     * @author wkangle
     * @time 2021/12/15 0015 16:00
     * @exception/throws
     */
    @Override
    public List<StoreInfoVo> queryStoreList(Map<String, Object> reqVo) {
        Double currentLatitude = PublicUtil.isNotEmpty(reqVo.get("currentLatitude")) ? Double.valueOf(reqVo.get("currentLatitude").toString()) : null; // 当前坐标纬度
        Double currentLongitude = PublicUtil.isNotEmpty(reqVo.get("currentLongitude")) ? Double.valueOf(reqVo.get("currentLongitude").toString()) : null; // 当前坐标经度
		System.out.println("currentLatitude: " + currentLatitude);
		System.out.println("currentLongitude: " + currentLongitude);

		// 2022-03-09 14:52:07【2.2-服务包配置需求】门店表、服务商表分别配置服务商标识字段apiCode，门店列表查询时，根据该apiCode查询对应服务商推送的门店信息
		String packageCode = PublicUtil.isNotEmpty(reqVo.get("packageCode")) ? reqVo.get("packageCode").toString() : null;
		if (PublicUtil.isNotEmpty(packageCode)) {
			StorePackageEntity storePackageEntity = storePackageDao.queryByPackageCode(packageCode);
			String valueAddServiceProviderId = storePackageEntity.getServer();
			Map<String, Object> params = new HashMap<>();
			params.put("id", Long.valueOf(valueAddServiceProviderId));
			ValueAddedServiceProviderEntity valueAddedServiceProviderEntity = valueAddedServiceProviderDao.getOneByParams(params);
			reqVo.put("apiCode", valueAddedServiceProviderEntity.getApiCode());
		}

		if (PublicUtil.isNotEmpty(currentLatitude) && PublicUtil.isNotEmpty(currentLongitude)) {
			List<StoreInfoVo> list = storeInfoDao.queryStoreList(reqVo);
			if (list.size() > 0) {
				for (StoreInfoVo vo : list) {
					// 门店坐标
					String coordinate = vo.getCoordinate();
					String[] split = coordinate.split(",");

					// 计算门店和当前坐标的距离
					GlobalCoordinates source = new GlobalCoordinates(currentLatitude, currentLongitude);
					GlobalCoordinates target = new GlobalCoordinates(Double.valueOf(split[1]), Double.valueOf(split[0]));
					double sphereMeter = getDistanceMeter(source, target, Ellipsoid.Sphere);
					vo.setSphereMeter(sphereMeter);
					//vo.setSphereMeter(Double.parseDouble(String.format("%.2f", sphereMeter / 1000)) + "KM");
				}
				// 根据距离排序
				List<StoreInfoVo> sortVoListBySphereMeter = list.stream().sorted(Comparator.comparing(StoreInfoVo::getSphereMeter)).collect(Collectors.toList());
				return sortVoListBySphereMeter;
			} else {
				return null;
			}
		} else {
			return null;
		}
    }

    // 计算距离
    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid) {
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
        return geoCurve.getEllipsoidalDistance();
    }

    public static void main(String[] args) {
        //GlobalCoordinates source = new GlobalCoordinates(31.12055, 121.717594);
        //GlobalCoordinates target = new GlobalCoordinates(31.090867, 121.817629);

		GlobalCoordinates source = new GlobalCoordinates(40.04269020659693, 116.37922122840918);
		GlobalCoordinates target = new GlobalCoordinates(29.865972, 121.561715);
        double sphereMeter = getDistanceMeter(source, target, Ellipsoid.Sphere);
        System.out.println(Double.parseDouble(String.format("%.2f", sphereMeter / 1000)) + "KM");
    }

    /**
	*
	* @author WANGCONG
	* 2021年12月20日下午17:18:16
	* @desc 门店信息插入
	*/
	@Override
	public int insert(StoreInfoEntity storeInfoEntity) {
		return storeInfoDao.insert(storeInfoEntity);
	}

	/**
	*
	* @author WANGCONG
	* 2021年12月21日上午9:19:36
	* @desc 门店信息更新
	*/
	@Override
	public int update(StoreInfoEntity storeInfoEntity) {
		return storeInfoDao.update(storeInfoEntity);
	}

	/**
	*
	* @author WANGCONG
	* 2021年12月21日上午9:20:19
	* @desc 门店信息删除
	*/
	@Override
	public int delete(StoreInfoEntity storeInfoEntity) {
		return storeInfoDao.delete(storeInfoEntity);
	}

}
